<template>
  <div class="center"
  v-show="isImageUrl(bgImage)&&showBgImage"
       style="user-select: none;
      -webkit-touch-callout: none;
      outline: none;
      -webkit-tap-highlight-color: transparent;
      border: none;
            pointer-events: none;
      -webkit-user-drag: none;"
       :style="backgroundTransparent?{'background-color':'transparent'}:{ 'background-image': 'url(' + bgImage + ')', 'filter': 'blur(8px)' }"></div>
  <iframe ref="iframeback" v-show="!isImageUrl(bgImage)&&showBgImage" :style="{
        width: resolutionPolicy.width + 'px',
        height: resolutionPolicy.height + 'px',
        position: 'absolute',
        transformOrigin: '0 0',
        left: '50%',
        transform: iframeBackTransform,
        top: '50%'
      }" :src="bgImage"></iframe>
  <div class="center" style="    overflow: hidden;">
    <Scalebox
        :width="resolutionPolicy.width"
        :height="resolutionPolicy.height"
        :delay="100"
        :bgColor="'#ffffff00'"
        :bgImage="showBgImage?bgImage:''"
        :backgroundTransparent="backgroundTransparent"
        :ResolutionPolicy="resolutionPolicy.policy"
        @scaleChange="scaleChange"
        ref="scaleBoxRef"
    >
      <!-- livekit语音 -->
      <LivekitManager
          :url="livkitUrl"
          :token="livkitToken"
          :currentProjectType="currentProjectType"
          ref="livekitManagerRef"
      ></LivekitManager>
      <!-- 数字人web端渲染 -->
      <AiHumanWebRenderer
          v-if="webHumanUrl&&currentProjectType == 'Web3d'"
          :full-body="fullBody"
          :url="webHumanUrl"
          :actionList="webHumanActionList"
          :x="'0'"
          :y="'0'"
          :scale="webHumanParams.scale"
          :style="'transform: translate('+webHumanParams.x+'px, '+webHumanParams.y+'px);opacity:'+webHumanParams.opacity+';'"
          :width="webHumanParams.width"
          :height="webHumanParams.height"
          ref="webhumanRenderRef"
      >
      </AiHumanWebRenderer>
      <!-- 数字人ue端渲染 -->
      <AiHumanUeRenderer
          :x="ueHumanParams.x"
          :y="ueHumanParams.y"
          :width="ueHumanParams.width"
          :height="ueHumanParams.height"
          :opacity="ueHumanParams.opacity"
          v-if="currentProjectType == 'UE3d'&&ueHumanUrl"
          :ueUrl="ueHumanUrl"
          :ueStreamerId="ueHumanStreamerId"
      >
      <button class="center" :style="'transform:translate('+ueHumanParams.x+'px,'+ueHumanParams.y+'px);'">
        播放
      </button>
    </AiHumanUeRenderer>
      <!-- 数字人2d端渲染 -->
      <AiHuman2dRenderer
          :x="Human2dParams.x"
          :y="Human2dParams.y"
          :width="Human2dParams.width"
          :height="Human2dParams.height"
          v-if="Human2dUrl"
          :stream_id="Human2dUrl"
          :human2dConfig="Human2dConfig"
          :enableChromaKey="sceneStore.projectConfig.uiConfig.modelSet.enableChromaKey == '1'"
          :backgroundColor="sceneStore.projectConfig.uiConfig.modelSet.backgroundColor?sceneStore.projectConfig.uiConfig.modelSet.backgroundColor:'#52ff52'"
          ref="webhuman2dRenderRef"
      ></AiHuman2dRenderer>
      <!-- 对话框 -->
      <ChatBox
          v-if="sceneStore.projectConfig"
          :boxType=chatboxParams.box.type
          :box=chatboxParams.box
          :input=chatboxParams.input
          :questions=chatboxParams.questions
          :commonQuestions="chatboxParams.questions.commonQuestions"
          :platform="sceneStore.projectConfig.projectSet.platform"
          ref="chatboxRef"
      ></ChatBox>
      <!-- 图片 -->
      <Animation :show-anim="true" v-for="(image,index) in imageList" :key="index" :animation="image.animation"
                 :animationOption="image.animationOption">
        <img class="center"
             :style="'transform: translate('+image.x+'px, '+image.y+'px);'+'left:0px;top:0px;width:'+image.width+'px;height:'+image.height+'px;z-index: '+image.zindex+';'"
             :src="origin+image.url">
      </Animation>
      <!-- 视频 -->
      <Animation :show-anim="true" v-for="(video,index) in videoList" :key="index" :animation="video.animation"
                 :animationOption="video.animationOption">
        <video controls class="center"
               :style="'transform: translate('+video.x+'px, '+video.y+'px);'+'left:0px;top:0px;width:'+video.width+'px;height:'+video.height+'px;z-index: '+video.zindex+';'"
               :src="origin+video.url"></video>
      </Animation>
      <!-- 流程节点图片 -->
      <Animation :ref="setAnimationRef" v-for="(image,index) in flowImageList" :key="image.id"
                 :timelineData="image.timelineData">
        <img class="center"
             :style="'transform: translate('+image.x+'px, '+image.y+'px);'+'left:0px;top:0px;width:'+image.width+'px;height:'+image.height+'px;z-index: '+image.zindex+';'"
             :src="origin+image.url">
      </Animation>
      <!-- 流程节点视频 -->
      <Animation :ref="setAnimationRef" v-for="(video,index) in flowVideoList" :key="index"
                 :timelineData="video.timelineData">

        <video class="center" autoplay
               :style="'transform: translate('+video.x+'px, '+video.y+'px);'+'left:0px;top:0px;width:'+video.width+'px;height:'+video.height+'px;z-index: '+video.zindex+';'"
               :src="origin+video.url"></video>

      </Animation>
      <!-- 流程节点svg动画 -->
      <Animation :ref="setAnimationRef" v-for="(svgAnim,index) in flowSvgAnimList" :key="index"
                 :timelineData="svgAnim.timelineData">


        <Lottie
            class="center"
            :x="svgAnim.x"
            :y="svgAnim.y"
            :width="svgAnim.width"
            :height="svgAnim.height"
            :zIndex="svgAnim.zindex"
            :opacity="svgAnim.opacity"
            :ref="setSvgAnimRef"
            :timelineData="svgAnim.timelineData"
        ></Lottie>
      </Animation>
      <!-- 网页 -->
      <Animation :show-anim="true" v-for="(iframe,index) in iframeList" :key="index" :animation="iframe.animation"
                 :animationOption="iframe.animationOption">
        <iframe class="center"
                :style="'transform: translate('+iframe.x+'px, '+iframe.y+'px);'+'left:0px;top:0px;width:'+iframe.width+'px;height:'+iframe.height+'px;z-index: '+iframe.zindex+';'"
                :src="'https://'+iframe.url"></iframe>
      </Animation>
      <!-- 文字 -->
      <Animation :show-anim="true" v-for="(text,index) in textList" :key="index" :animation="text.animation"
                 :animationOption="text.animationOption">
        <div class="center"
             :style="'transform: translate('+text.x+'px, '+text.y+'px);'+'left:0px;top:0px;width:'+text.width+'px;height:'+text.height+'px;z-index: '+text.zindex+';'">
          <el-text line-clamp="2" :style="text.style">{{ text.text }}</el-text>
        </div>
      </Animation>
      <!-- 富文本 -->
      <Animation :show-anim="true" v-for="(text,index) in htmlTextList" :key="index" :animation="text.animation"
                 :animationOption="text.animationOption">
        <div class="center"
             :style="'transform: translate('+text.x+'px, '+text.y+'px);'+'left:0px;top:0px;width:'+text.width+'px;height:'+text.height+'px;z-index: '+text.zindex+';'">
          <div
              v-html="text.text"
              readonly
              style="left:0px;top:0px;width:100%;height:100%; outline: none;resize:none;"
          ></div>
        </div>
      </Animation>
      <!-- 字幕 -->
      <Captions
          v-if="captionsParams.enable"
          :text="currentText"
          v-show="currentText&&currentText!=''"
          :x="'0'"
          :y="'0'"
          :zindex="captionsParams.zindex"
          :style="'transform: translate('+captionsParams.x+'px, '+captionsParams.y+'px)'"
          :width="captionsParams.width"
          :height="captionsParams.height"
          :captionStyle="captionsParams.style"
      ></Captions>
      <!-- 操作栏 -->
      <cornerControl
          v-if="cornerControlParams.enable"
          :controlOptions="cornerControlParams"
          :platform="currentProjectPlatform"
      ></cornerControl>
      <!-- 语音输入组件 -->
      <VoiceInput
          v-if="voiceInputParams.enable&&currentProjectPlatform == 'screen'"
          :x="'0'"
          :y="'0'"
          :style="'transform: translate('+voiceInputParams.x+'px, '+voiceInputParams.y+'px)'"
          :width="voiceInputParams.width"
          :height="voiceInputParams.height"
          :iconUrl="voiceInputParams.url"
      ></VoiceInput>
      <Interrupt
          v-show="false"
          v-if="interruptParams.buttonInterrupt || interruptParams.tip"
          :buttonInterrupt="interruptParams.buttonInterrupt"
          :buttonOptions="interruptParams.buttonOptions"
          :tip="interruptParams.tip"
          :tipOptions="interruptParams.tipOptions"
          :voiceInterruptWords="interruptParams.voiceInterruptWords"
          :interruptResponses="interruptParams.interruptResponses"
      ></Interrupt>
      <!-- <el-button type="primary" @click="testImage">测试图片</el-button>
      <el-button type="primary" @click="testVideo">测试视频</el-button>
      <el-button type="primary" @click="testIframe">测试网页</el-button>
      <el-button type="primary" @click="testText">测试文字</el-button>
      <el-button v-if="webHumanActions.length>0" v-for="(btn,index) in webHumanActions" type="primary" @click="testAction(btn)">测试动作{{ btn }}</el-button>
      <el-button v-if="flowNodes.length>0" v-for="(flowNode,index) in flowNodes" type="primary" @click="setFlowNode(flowNode)">测试节点{{ index }}</el-button> -->
      <!-- <el-button v-if="webHumanCostumeList.length>0" v-for="(btn,index) in webHumanCostumeList" type="primary" @click="changeCostum(btn)">切换服装{{ index }}</el-button> -->
    </Scalebox>
  </div>

  <timeline v-show="showTimeline == '1'" ref="timelineRef" :flowNode="currentFlowNode"></timeline>
  <div style="position: absolute;pointer-events: none;width: 100%;height: 100%;z-index: 999;" id="externalUI"></div>
  <div v-if="currentSleepState"
       style="overflow: hidden;position: absolute;width: 100%;height: 100%;z-index: 999;background-color: #00000044;"
       id="sleepUI">
    <el-carousel
        height="100%"
        style="width: 100%;height:100%;"
        :autoplay="true"
        :interval="3000"
        :loop="true"
        v-if="currentSleepType == 'image'"
    >
      <el-carousel-item v-for="item in sceneStore.projectConfig.sleepConfig.sleepParams.imageList" :key="item">
        <el-image style="width: 100%; height: 100%" :src="origin+item.url" :fit="'contain'"/>
      </el-carousel-item>
    </el-carousel>
    <video id="videoSleep" ref="videoSleepRef" v-if="currentSleepType == 'video'"
           style="object-fit: contain;width: 100%; height: 100%"
           :src="origin+sceneStore.projectConfig.sleepConfig.sleepParams.videoList[currentSleepVideoIndex].url"
           :autoplay="true"></video>
    <h3
        style="position: absolute;top: 60%;left: 50%;transform: translate(-50%, -50%);color: #fff;background-color: #00000044;    border-radius: 5px;
    padding: 10px;"
        v-if="sceneStore.projectConfig.wakeConfig.wakeParams.wakeTip&&sceneStore.projectConfig.wakeConfig.wakeParams.wakeTip!=''">
      {{ sceneStore.projectConfig.wakeConfig.wakeParams.wakeTip }}
    </h3>
    <el-button class="wakeup-btn" type="primary" @click="wakeUp(false)">退出睡眠</el-button>

  </div>
</template>
<script setup lang="ts">
import {ref, onMounted, onBeforeUnmount, getCurrentInstance,nextTick} from 'vue'
import Scalebox from "../../components/scaleBox/index.vue"
import AiHumanWebRenderer from "@/components/aiHumanWebRenderer/index.vue"
import LivekitManager from "@/components/livekitManager/index.vue"
import ChatBox from "@/components/chatBox/index.vue"
import Captions from "@/components/cations/index.vue"
import cornerControl from "@/components/cornerControl/index.vue"
import Animation from "@/components/animation/index.vue"
import AiHumanUeRenderer from "@/components/aiHumanUeRenderer/index.vue"
import AiHuman2dRenderer from "@/components/AiHuman2dRenderer/index.vue"
// 在 import 部分添加
import VoiceInput from "@/components/voiceInput/index.vue"
// 在 import 部分添加
import Interrupt from "@/components/interrupt/index.vue"
import Lottie from "@/components/Lottie/index.vue"
import timeline from "@/components/timeline/index.vue"
import {mittTypes} from "@/util/types"
import * as THREE from 'three'
import {
  getCanOpenAndOpen2d,
  get2dResourceApplyResult,
  close2d,
  closeRoom,
  closeUe,
  getCanOpenAndOpenUe,
  getProjectAllConfigInfo,
  getTokenToBegin,
  getAimetaProjectManagerdetailInfo,
  getAimetaManagerdetailInfo
} from "@/api/apiRequst"
import {getUrlParam, uuid} from "@/util/common.js"
import {useSceneStore} from '@/stores/scene'
import $ from 'jquery'
import {ElMessage, translate} from 'element-plus'
import {asynRemove, asynLoad, addCss,sendMessageToParent} from "@/util/common.js"
import '@/styles/richText.less'
import { animate } from "motion"
import pinyin from 'pinyin' ;
import { DataCommand } from '@/components/livekitManager/message'
// 判断URL是否为图片格式
const isImageUrl = (url) => {
  if (!url) return false
  const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.bmp', '.svg']
  const urlLower = url.toLowerCase()
  return imageExtensions.some(ext => urlLower.includes(ext))
}
const showBgImage = ref(true);
showBgImage.value = getUrlParam('hideBgImage')=='1'?false:true



let timeout = setTimeout(() => {

  }, 10000);
const sceneStore = useSceneStore();

const {appContext: {config: {globalProperties}}} = getCurrentInstance();

const internalInstance = getCurrentInstance()
const emitter = internalInstance.appContext.config.globalProperties.emitter
const origin = internalInstance.appContext.config.globalProperties.origin
const backgroundTransparent = getUrlParam('transparent')
const showTimeline = getUrlParam('showTimeline')
if (backgroundTransparent) {
  // 添加透明背景样式到文档
  document.documentElement.style.backgroundColor = 'transparent';
  document.body.style.backgroundColor = 'transparent';
  // // 取消 color-scheme 属性，防止系统默认样式影响透明效果
  // document.documentElement.style.colorScheme = 'normal';
}
// SHOW_ALL 
// 整个应用程序在指定区域可见，没有变形，同时保持原始纵横比，边框可能出现在画面的旁侧。
// FIXED_WIDTH 
// 该应用程序采用设计分辨率大小的宽度并修改内部画布的高度，使其适合设备的纵横比，不会发生变形但是您必须确保您的应用程序在不同的纵横比的设备下工作。
// FIXED_HEIGHT 
// 该应用程序采用设计分辨率大小的高度并修改内部画布的宽度，使其适合设备的纵横比，不会发生变形，但是您必须确保您的应用程序在不同的纵横比的设备下工作。
// EXACT_FIT 
// 整个应用程序在指定区域可见，无需尝试保留原始纵横比，可能会发生变形，出现画面拉伸或压缩。
const scaleBoxRef = ref(null)
const iframeBackTransform = ref('translate(-50%, -50%)')
// 创建一个函数来更新 transform 值
const updateIframeTransform = () => {
  if (scaleBoxRef.value && scaleBoxRef.value.getScaleX && scaleBoxRef.value.getScaleY) {
    try {
      switch(resolutionPolicy.value.policy){
        case "SHOW_ALL":
          var scaleX = scaleBoxRef.value.getScaleX()
          var scaleY = scaleBoxRef.value.getScaleY()
          iframeBackTransform.value = `scale(${scaleX}, ${scaleY}) translate(-50%, -50%)`
          break;
        case "FIXED_WIDTH":
          var scaleX = scaleBoxRef.value.getScaleX()
          var scaleY = scaleBoxRef.value.getScaleX()
          iframeBackTransform.value = `scale(${scaleX}, ${scaleY}) translate(-50%, -50%)`
          break;
        case "FIXED_HEIGHT":
          var scaleX = scaleBoxRef.value.getScaleY()
          var scaleY = scaleBoxRef.value.getScaleY()
          iframeBackTransform.value = `scale(${scaleX}, ${scaleY}) translate(-50%, -50%)`
          break;
        case "EXACT_FIT":
          var scaleX = scaleBoxRef.value.getScaleX()
          var scaleY = scaleBoxRef.value.getScaleY()
          iframeBackTransform.value = `scale(${scaleX}, ${scaleY}) translate(-50%, -50%)`
          break;
      }
      // iframeBackTransform.value = `scale(${scaleX}, ${scaleY}) translate(-50%, -50%)`
    } catch (error) {
      console.warn('获取缩放比例时出错:', error)
      iframeBackTransform.value = 'translate(-50%, -50%)'
    }
  } else {
    iframeBackTransform.value = 'translate(-50%, -50%)'
  }
}

const resizeObserver = new ResizeObserver(entries => {
  // 回调中调用更新函数
  updateIframeTransform()
})
const resolutionPolicy = ref({
  policy: 'FIXED_WIDTH',
  width: 1920,
  height: 1080,
})
const scaleX = ref(1)
const scaleChange = function (scaleVal: any) {
  /*
    默认为宽度适配模式(等比缩放)
    FIXED_WIDTH/FIXED_HEIGHT/SHOW_ALL scaleVal = [x缩放值, y缩放值]
    EXACT_FIT scaleVal = 等比缩放值
  */
  // scale.value = 1 / scaleVal;
  // if(scaleBoxRef.value){
  //   for(let i=0;i<scaleBoxRef.value.rocScaleBox.children.length;i++){
  //     let width = parseFloat(scaleBoxRef.value.rocScaleBox.children[i].style.width.replace('px',''))
  //     let height = parseFloat(scaleBoxRef.value.rocScaleBox.children[i].style.height.replace('px',''))
  //     switch(resolutionPolicy.value){
  //         case "SHOW_ALL":
  //           scaleBoxRef.value.rocScaleBox.children[i].style.transform = "scale("+1/scaleVal+")";
  //           break;
  //         case "FIXED_WIDTH":
  //           scaleBoxRef.value.rocScaleBox.children[i].style.transform = "scaleX("+1/scaleVal[0]+")";
  //           scaleX.value = 1/scaleVal[0];
  //           break;
  //         case "FIXED_HEIGHT":

  //           scaleBoxRef.value.rocScaleBox.children[i].style.transform = "scaleY("+1/scaleVal[1]+")"

  //           break;
  //         case "EXACT_FIT":
  //           scaleBoxRef.value.rocScaleBox.children[i].style.transform = "scaleX("+1/scaleVal[0]+") scaleY("+1/scaleVal[1]+")"
  //         break;
  //     }
  //     scaleBoxRef.value.rocScaleBox.children[i].style.transformOrigin = "center"
  //   }
  // }
}
const livekitManagerRef = ref(null)
const currentSleepState = ref(false)
const currentSleepType = ref('')
const currentSleepVideoIndex = ref(0)
const currentSleepFlowNodeIndex = ref(0)
const videoSleepRef = ref()
const sleepTime = ref(30)
const bgImage = ref('https://aiimg.huilan.com/aiHuman/images/back.jpg')
const flowImageList = ref([])
const flowVideoList = ref([])
const flowSvgAnimList = ref([])
const webhuman2dRenderRef = ref(null)
const isplaying = ref(false)

const currentProjectType = ref('')
const currentProjectPlatform = ref('pc')
const currentInputType = ref('Multi')
const currentFlowNode = ref()
const imageList = ref([])
const videoList = ref([])
const iframeList = ref([])
const textList = ref([])
const htmlTextList = ref([])
const actionList = ref([])
const currentText = ref("")
const livkitToken = ref(null)
const livkitUrl = ref(null)
const ueHumanServerId = ref(null)
const ueHumanUrl = ref(null)
const Human2dUrl = ref(null)
const Human2dConfig = ref({
  urls: '',
  username: '',
  credential: '',
})
const resource2dCode = ref(null)
const ueHumanStreamerId = ref(null)
const Human2dStreamerId = ref(null)
const webHumanUrl = ref(null)
const webHumanCostumeList = ref([])
const webHumanActionList = ref([])
const webHumanActions = ref([])
const flowNodes = ref([])
const timelineRef = ref()
const webhumanRenderRef = ref()
const fullBody = ref(false)
const chatboxRef = ref(null)
const webHumanParams = ref({
  x: -700, y: -100, width: 500, height: 600,opacity:1,scale:1
})
const ueHumanParams = ref({
  x: "-600", y: "0", width: "768", height: "864",opacity:'1',scale:'1'
})
const Human2dParams = ref({
  x: "-600", y: "0", width: "768", height: "864"
})
const chatboxParams = ref({
  box: {
    "x": 233,
    "y": -90,
    "width": 710,
    "height": 590,
    "type": "multi", //多条multi 单挑single,
    "opacity": 0,
    "backgroundColor": "#000000",
    "fontSize": 12,
    "headImg": "default"
  },
  input: {

    "x": 236,
    "width": 718,
    "y": 292,
    "height": 64,
    "type": "audioText", //语音audio 文字text 语音加文字audioText,
    "opacity": 0,
    "backgroundColor": "#000000",
    "fontSize": 12,
  },
  questions: {

    "x": 232,
    "y": 227,
    "width": 707,
    "height": 34,
    "type": "manual", //自定义manual 自动匹配auto,
    "opacity": 0,
    "backgroundColor": "#000000",
    "fontSize": 12,
    commonQuestions: ['你是谁']
  },
  zindex: 10,
})
const captionsParams = ref({
  enable: false,
  zindex: 10,
  x: "0", y: "700", width: "1500", height: "50",
  style: {
    "lineHeight": '1.5',
    "fontSize": '20px',
    "fontFamily": "宋体",
    "color": "#ff0000",
    "fontItalic": false,
    "fontBold": false,
    "border-radius": "10px",
    "background-color": "#ffffff9e",
    "box-shadow": " 0px 0px 20px 0px #ad00ff69",
    "border": "2px solid #ad00ff69",
    "padding": '20px',
    "fontUrl": "http://172.20.0.187:9000/000000/ttf_1672312784193.ttf",
    "height": "auto",
    "text-align": "left",
    "position": "relative"
  }
})
const cornerControlParams = ref( { 
        "enable":true,
        "x":830, //pc 830  mobile/screen 306
        "y": -450, //pc -450 mobile/screen -224
        "width": 54, //pc 54  mobile/screen 54
        "height": 54, //pc 54 mobile/screen 54
        "opacity":1,
        "backgroundColor":"#ffffff00",
        "zindex":0,
        "muteControl":{
            "enable":true,
            "name":"静音",
            "activeUrl":"@/assets/images/laba-on.png",
            "deActiveUrl": "@/assets/images/laba-off.png"
          }
      })
const voiceInputParams = ref({
  enable: false,
  x: "20",
  y: "80",
  width: "60",
  height: "60",
  zindex: 10,
  opacity: 1,
  url: origin + "/aihumanEdit/UIasset/image/voice.png"
})
// 在 script 部分添加 interruptParams 的定义
const interruptParams = ref({
  buttonInterrupt: true,
  buttonOptions: {
    x: 20,
    y: 20,
    width: 160,
    height: 60,
    zindex: 10
  },
  tip: true,
  tipOptions: {
    x: 80,
    y: 20,
    width: 200,
    height: 40,
    zindex: 10
  },
  voiceInterruptWords: ['别说了', '我知道了'],
  interruptResponses: [
    {text: '好的，您还可以问我其他问题哦~', flowNode: null},
    {text: '好的，您还可以说一下其他感兴趣的话题问我哦~', flowNode: null}
  ]
})

function testImage() {
  imageList.value = [
    {
      "url": "https://aiimg.huilan.com/aiDraw/lei.jpg", //图片url
      "startTime": "00:00:00:00",
      "endTime": "00:00:02:650",
      "x": -500, //位置
      "y": -50, //位置
      "width": 200, //宽度
      "height": 200, //高度
      "scale": 1.0, //缩放
      "zIndex": 11, //层级
      "alwaysShow": false, //是否一直显示
      //使用motion one动画库，参照文档https://motion.dev/docs/animate
      // animation为一个动画序列
      "animation": [
        {
          "animAttri": {"opacity": [0, 1], "x": -400, "y": -50},
          "animOption": {"duration": 2, "autoplay": true}
        },
        {
          "animAttri": {"opacity": [1, 0], "x": -400, "y": 150},
          "animOption": {"duration": 2, "autoplay": true, "delay": 2}
        }
      ],
      "animationOption": {delay: 0.5}
    }
  ]
}

function testVideo() {
  videoList.value = [
    {
      "url": "https://aiimg.huilan.com/material/video/bucket-1690973302633086978/1831991325539487746.mp4", //网页url
      "loop": false,
      "startTime": "00:00:00:00",
      "endTime": "00:00:00:173",
      "x": -500, //位置
      "y": -50, //位置
      "width": 960,
      "height": 200.0,
      "scale": 1,
      "zIndex": 13, //层级
      "alwaysShow": false,
      //使用motion one动画库，参照文档https://motion.dev/docs/animate
      // animation为一个动画序列
      "animation": [
        {
          "animAttri": {"opacity": [0, 1], "x": -400, "y": -50},
          "animOption": {"duration": 2, "autoplay": true}
        },
        {
          "animAttri": {"opacity": [1, 0], "x": -400, "y": 150},
          "animOption": {"duration": 2, "autoplay": true, "at": 4}
        }
      ],
      "animationOption": {delay: 0.5}
    }
  ]
}

function testIframe() {
  iframeList.value = [
    {
      "url": origin + "", //网页url
      "startTime": "00:00:00:00",
      "endTime": "00:00:00:173",
      "x": 0,
      "y": 0,
      "width": 500,
      "height": 400.0,
      "scale": 1,
      "zIndex": 14, //层级
      "alwaysShow": false,
      //使用motion one动画库，参照文档https://motion.dev/docs/animate
      // animation为一个动画序列
      "animation": [
        {
          "animAttri": {"opacity": [0, 1], "x": -400, "y": -50},
          "animOption": {"duration": 2, "autoplay": true}
        },
        {
          "animAttri": {"opacity": [1, 0], "x": -400, "y": 150},
          "animOption": {"duration": 2, "autoplay": true, "delay": 2}
        }
      ],
      "animationOption": {delay: 0.5}
    }
  ]
}

function testText() {
  textList.value = [
    {
      "text": "这是新添加的文字", //文字
      "startTime": "00:00:00:00",
      "endTime": "00:00:01:213",
      "x": 100,
      "y": 0,
      "width": 400, //宽度
      "height": 50, //高度
      "scale": 1,
      "zIndex": 15, //层级
      "alwaysShow": false,
      "style": {
        "fontSize": "30px",
        "fontFamily": "宋体",
        "color": "#ff0000",
        "fontItalic": false,
        "fontBold": false,
        "fontUrl": "http://172.20.0.187:9000/000000/ttf_1672312784193.ttf"
      },
      //使用motion one动画库，参照文档https://motion.dev/docs/animate
      // animation为一个动画序列
      "animation": [
        {
          "animAttri": {"opacity": [0, 1], "x": -400, "y": -50, "scale": [0, 1.5]},
          "animOption": {"duration": 2, "autoplay": true}
        },
        {
          "animAttri": {"opacity": [1, 0], "x": -400, "y": 150},
          "animOption": {"duration": 2, "autoplay": true, "delay": 1}
        }
      ],
      "animationOption": {delay: 0.5}
    }
  ]
}

function testAction(name: any) {
  // emitter.emit(mittTypes.LIVEKIT.MESSAGE_ACTION_RECIVE,name)
  webhumanRenderRef.value.generateGif(name)
}

function changeCostum(url: any) {
  // emitter.emit(mittTypes.LIVEKIT.MESSAGE_ACTION_RECIVE,'F-91L_双手放小腹_右手指向右侧_长距离')
  // emitter.emit(mittTypes.LIVEKIT.MESSAGE_ACTION_RECIVE,name)
  emitter.emit(mittTypes.WEBHUMAN.CHANGE_COSTUME, url)
}

// 测试流程节点
function setFlowNode(flowNode: any) {
  if(!livekitFlowNodePlaying.value){
    return;
  }
  // emitter.emit(mittTypes.LIVEKIT.MESSAGE_ACTION_RECIVE,'F-91L_双手放小腹_右手指向右侧_长距离')
  // emitter.emit(mittTypes.LIVEKIT.MESSAGE_ACTION_RECIVE,name)
  //向父窗口发送默认进入事件
  sendMessageToParent('timeline-event','timeline-enter',{speechText:sceneStore.currentFlowNodes[curLivekitFlowNodeIndex.value].speechWordsList[0].timelineData.speechData[0].text,id:sceneStore.currentFlowNodes[curLivekitFlowNodeIndex.value].id,question:sceneStore.currentQuestion,questionType:sceneStore.currentQuestionType})

  console.log("设置流程节点", flowNode)
  sceneStore.currentFlowNode = flowNode
  if(flowNode.speechWordsList.length>0){
    currentText.value = flowNode.speechWordsList[0].timelineData.speechData[0].text
  }
  currentFlowNode.value = flowNode;
  emitter.emit(mittTypes.TIMELINE.UPDATE_TIMELINE_DATA)
  flowImageList.value = flowNode.imageList;
  flowVideoList.value = flowNode.videoList;
  flowSvgAnimList.value = flowNode.svgAnimList;
  isplaying.value = true;
  setTimeout(function () {
    timelineRef.value.play();
  }, 50)

}

const curLivekitFlowNodeIndex = ref(0)
const livekitFlowNodePlaying = ref(false)
const stopLivekitFlowNodeList = ref(false)
const roleMoving = ref(false)

function addLivekitFlowNode(flowNode: any) {
  // if(stopLivekitFlowNodeList.value){
  //   return;
  // }
  if(roleMoving.value){
    return;
  }
  if(currentProjectPlatform.value == 'guide'){
    // 根据项目类型选择对应的参数对象
    const targetParams = currentProjectType.value === 'UE3d' ? ueHumanParams : webHumanParams;

    if(flowNode.roleConfig&&flowNode.roleConfig.enableTransition){
      
      // 移动动作
      let moveSpeed = 150
      // 需要移动
      if(flowNode.roleConfig.x<parseFloat(targetParams.value.x)){
        roleMoving.value = true;
        emitter.emit(mittTypes.LIVEKIT.AUDIO_ENABLE, false)
          if(currentProjectType.value === 'Web3d'){
              let time = (parseFloat(targetParams.value.x-flowNode.roleConfig.x))/moveSpeed
                emitter.emit(mittTypes.WEBHUMAN.ACTIVE_BASE_ACTION,{name:'Move_R ',loopType:THREE.LoopRepeat,callback:null,noCross:false})
                let target = {
                  x: parseFloat(flowNode.roleConfig.x),
                  y: parseFloat(flowNode.roleConfig.y),
                  width: parseFloat(flowNode.roleConfig.width),
                  height: parseFloat(flowNode.roleConfig.height)
                }
                // 使用motion动画改变webHumanParams的位置
                let start = targetParams.value
                animate(targetParams.value, target, {
                  duration: time , // 转换为秒
                   ease: "linear",

                }).then(() => {
                  emitter.emit(mittTypes.WEBHUMAN.ACTIVE_BASE_ACTION,{name:'Move_R _2',loopType:THREE.LoopOnce,callback:function(action){
                    if(action._clip.name != 'Move_R _2'){
                      return
                    }
                    roleMoving.value = false;
                    emitter.emit(mittTypes.LIVEKIT.AUDIO_ENABLE, true)
                    // emitter.emit(mittTypes.WEBHUMAN.STOP_BASE_ACTION,flowNode.roleConfig.actionMoveRight.name)
                    sceneStore.currentFlowNodes.push(flowNode)
                    if (!livekitFlowNodePlaying.value) {
                      playLivekitFlowNodeList()
                    }
                    console.log("Livekit节点列表", sceneStore.currentFlowNodes)
                  }})

                })
          }else if(currentProjectType.value === 'UE3d'){
            roleMoving.value = true;
            emitter.emit(mittTypes.LIVEKIT.DRIVE_UE_MOVE,{command:DataCommand.MOVE_START,data:'left'})
            setTimeout(() => {
              let time = (targetParams.value.x-parseFloat(flowNode.roleConfig.x))/moveSpeed
              let target = {
                x: parseFloat(flowNode.roleConfig.x),
                y: parseFloat(flowNode.roleConfig.y),
                width: parseFloat(flowNode.roleConfig.width),
                height: parseFloat(flowNode.roleConfig.height)
              }
              // 使用motion动画改变webHumanParams的位置
              let start = targetParams.value
              animate(targetParams.value, target, {
                duration: time , // 转换为秒
                  ease: "linear",

              }).then(() => {
                emitter.emit(mittTypes.LIVEKIT.DRIVE_UE_MOVE,{command:DataCommand.MOVE_END,data:'left'})
                setTimeout(() => {
                  roleMoving.value = false;
                  emitter.emit(mittTypes.LIVEKIT.AUDIO_ENABLE, true)
                  const multiData = livekitManagerRef.value.getMultiDataToShow()
                  if(multiData){
                     
                    emitter.emit(mittTypes.LIVEKIT.DRIVE_UE_MULTIDATA,{data:multiData})

                  }
                }, 4.17*1000);
                
              })
            }, 2.83*1000);
            
          }

         

      }else if(flowNode.roleConfig.x>parseFloat(targetParams.value.x)){
        roleMoving.value = true;
        emitter.emit(mittTypes.LIVEKIT.AUDIO_ENABLE, false)
        if(currentProjectType.value === 'Web3d'){
              let time = (flowNode.roleConfig.x-parseFloat(targetParams.value.x))/moveSpeed
            
              emitter.emit(mittTypes.WEBHUMAN.ACTIVE_BASE_ACTION,{name:'Move_L',loopType:THREE.LoopRepeat,callback:null,noCross:false})
              // 使用motion动画改变webHumanParams的位置
               let target = {
                  x: parseFloat(flowNode.roleConfig.x),
                  y: parseFloat(flowNode.roleConfig.y),
                  width: parseFloat(flowNode.roleConfig.width),
                  height: parseFloat(flowNode.roleConfig.height)
                }
                let start = targetParams.value
              animate(targetParams.value, target, {
                duration: time , // 转换为秒
                ease: "linear",
              
              }).then(() => {
                emitter.emit(mittTypes.WEBHUMAN.ACTIVE_BASE_ACTION,{name:'Move_L_2',loopType:THREE.LoopOnce,callback:function(action){
                  if(action._clip.name != 'Move_L_2'){
                    return
                  }
                  roleMoving.value = false;
                  // emitter.emit(mittTypes.WEBHUMAN.STOP_BASE_ACTION,flowNode.roleConfig.actionMoveLeft.name)
                  emitter.emit(mittTypes.LIVEKIT.AUDIO_ENABLE, true)
                  sceneStore.currentFlowNodes.push(flowNode)
                  if (!livekitFlowNodePlaying.value) {
                    playLivekitFlowNodeList()
                  }
                  console.log("Livekit节点列表", sceneStore.currentFlowNodes)
                }})
              })
        }else if(currentProjectType.value === 'UE3d'){
          roleMoving.value = true;
          emitter.emit(mittTypes.LIVEKIT.DRIVE_UE_MOVE,{command:DataCommand.MOVE_START,data:'right'})
          setTimeout(() => {
            let time = (flowNode.roleConfig.x-parseFloat(targetParams.value.x))/moveSpeed
            let target = {
                  x: parseFloat(flowNode.roleConfig.x),
                  y: parseFloat(flowNode.roleConfig.y),
                  width: parseFloat(flowNode.roleConfig.width),
                  height: parseFloat(flowNode.roleConfig.height)
                }
                // 使用motion动画改变webHumanParams的位置
            animate(targetParams.value, target, {
              duration: time , // 转换为秒
               ease: "linear",
            
            }).then(() => {
              emitter.emit(mittTypes.LIVEKIT.DRIVE_UE_MOVE,{command:DataCommand.MOVE_END,data:'right'})
              setTimeout(() => {
                roleMoving.value = false;
                emitter.emit(mittTypes.LIVEKIT.AUDIO_ENABLE, true)
                  const multiData = livekitManagerRef.value.getMultiDataToShow()
                  if(multiData){
                    emitter.emit(mittTypes.LIVEKIT.DRIVE_UE_MULTIDATA,{data:multiData})
                  
                  }
                }, 4.17*1000);
            })
          }, 2.83*1000);
          
        }

        
      }else{
        sceneStore.currentFlowNodes.push(flowNode)
        if (!livekitFlowNodePlaying.value) {
          playLivekitFlowNodeList()
        
        }
        console.log("Livekit节点列表", sceneStore.currentFlowNodes)
      }
    } else if(flowNode.roleConfig&&(!flowNode.roleConfig.enableTransition&&flowNode.roleConfig.actionMoveOut.enable)){

      // 出场动作
      if(currentProjectType.value === 'UE3d'){
        roleMoving.value = true;
        let time = 0;
        if(flowNode.roleConfig&&flowNode.roleConfig.actionMoveOut.effectEnable){
          if(flowNode.roleConfig.actionMoveOut.duration>(1.93+2.83)){
            time = flowNode.roleConfig.actionMoveOut.duration-(2.83)
            const multiData = livekitManagerRef.value.getMultiDataToShow()
            emitter.emit(mittTypes.LIVEKIT.DRIVE_UE_MOVE,{command:DataCommand.MOVE_START,data:'forward'})
            setTimeout(() => {
              emitter.emit(mittTypes.LIVEKIT.DRIVE_UE_MOVE,{command:DataCommand.MOVE_END,data:'forward'})
              setTimeout(() => {
                roleMoving.value = false;
                // if(multiData){
                //   emitter.emit(mittTypes.LIVEKIT.DRIVE_UE_MULTIDATA,{data:multiData})
                // }
              }, 2.83*1000+time);

            },1.93*1000+time)
          }else{
              const multiData = livekitManagerRef.value.getMultiDataToShow()
              emitter.emit(mittTypes.LIVEKIT.DRIVE_UE_MOVE,{command:DataCommand.MOVE_START,data:'forward'})
              setTimeout(() => {
                emitter.emit(mittTypes.LIVEKIT.DRIVE_UE_MOVE,{command:DataCommand.MOVE_END,data:'forward'})
                setTimeout(() => {
                  roleMoving.value = false;
                  if(multiData){
                    emitter.emit(mittTypes.LIVEKIT.DRIVE_UE_MULTIDATA,{data:multiData})
                  }
                }, 2.83*1000);

              },1.93*1000)
          }
        }
        
        
      }else if (currentProjectType.value === 'Web3d'){
        roleMoving.value = true;
        emitter.emit(mittTypes.WEBHUMAN.ACTIVE_BASE_ACTION,{name:'walk',loopType:THREE.LoopRepeat,callback:null,noCross:false})
        let time = 0;
        if(flowNode.roleConfig&&flowNode.roleConfig.actionMoveOut.effectEnable){
          // 读取设置的出场动作时间值
          time = flowNode.roleConfig.actionMoveOut.duration
          setTimeout(() => {
            roleMoving.value = false;
            emitter.emit(mittTypes.WEBHUMAN.STOP_BASE_ACTION,'walk')
            emitter.emit(mittTypes.WEBHUMAN.ACTIVE_BASE_ACTION,{name:'idle',loopType:THREE.LoopOnce,callback:null,noCross:false})
            // sceneStore.currentFlowNodes.push(flowNode)
            // if (!livekitFlowNodePlaying.value) {
            //   playLivekitFlowNodeList()
            // }
          }, time*1000);
        }else{
          // 默认3秒
          setTimeout(() => {
            roleMoving.value = false;
            emitter.emit(mittTypes.WEBHUMAN.STOP_BASE_ACTION,'walk')
            emitter.emit(mittTypes.WEBHUMAN.ACTIVE_BASE_ACTION,{name:'idle',loopType:THREE.LoopOnce,callback:null,noCross:false})
            sceneStore.currentFlowNodes.push(flowNode)
            if (!livekitFlowNodePlaying.value) {
              playLivekitFlowNodeList()
            }
          }, 3*1000);
        }
        
        
      }

      console.log("Livekit节点列表", sceneStore.currentFlowNodes)
    }else{
      sceneStore.currentFlowNodes.push(flowNode)
      if (!livekitFlowNodePlaying.value) {
        playLivekitFlowNodeList()

      }
      console.log("Livekit节点列表", sceneStore.currentFlowNodes)
    }
    if(flowNode.roleConfig&&flowNode.roleConfig.actionMoveOut.effectEnable){
      roleMoving.value = true;
      // 直接切换位置
        // emitter.emit(mittTypes.WEBHUMAN.STOP_BASE_ACTION,flowNode.roleConfig.actionMoveOut.animation)
        targetParams.value.scale = flowNode.roleConfig.actionMoveOut.originScale
      
        const sequence = [] as any
        // targetParams.value.x = parseFloat(flowNode.roleConfig.x)
        // targetParams.value.y = parseFloat(flowNode.roleConfig.y)
        // 第一步：opacity变为0，width和height设置为originScale乘以原值，时间0.5秒
        // sequence.push([targetParams.value, {
        //   opacity: 0,
        // }, {
        //   duration: 0.5,
        //   ease: "easeInOut"
        // }])
        let width = flowNode.roleConfig.actionMoveOut.originScale * parseFloat(flowNode.roleConfig.width);
        let height = flowNode.roleConfig.actionMoveOut.originScale * parseFloat(flowNode.roleConfig.height);
        console.log(width,height)
        console.log(flowNode.roleConfig.width,flowNode.roleConfig.height)
        let target = {
          x: parseFloat(flowNode.roleConfig.x),
          y: parseFloat(flowNode.roleConfig.y),
          opacity: parseFloat(flowNode.roleConfig.actionMoveOut.opacity),
          scale: parseFloat(flowNode.roleConfig.actionMoveOut.originScale),
          // width: width,
          // height: height
        }
        sequence.push([targetParams.value,target , {
          duration: 0.0,
          ease: "easeInOut"
        }])

        // 第二步：设置xy位置，opacity为1，width和height乘以1，时间为actionMoveOut.duration
        sequence.push([targetParams.value, {
          opacity: 1,
          scale: 1,
          // width: flowNode.roleConfig.width,
          // height: flowNode.roleConfig.height
        }, {
          duration: flowNode.roleConfig.actionMoveOut.duration,
          ease: "easeInOut"
        }])
        if(currentProjectType.value === 'UE3d'){
          const multiData = livekitManagerRef.value.getMultiDataToShow()
          if(multiData){
            animate(sequence, {delay: 0}).then(() => {
              // emitter.emit(mittTypes.WEBHUMAN.STOP_BASE_ACTION,flowNode.roleConfig.actionMoveOut.animation)
              console.log("Livekit节点列表", sceneStore.currentFlowNodes)
              emitter.emit(mittTypes.LIVEKIT.DRIVE_UE_MULTIDATA,{data:multiData})
              roleMoving.value = false;
            })
          }
        }else if (currentProjectType.value === 'Web3d'){
          animate(sequence, {delay: 0}).then(() => {
            // emitter.emit(mittTypes.WEBHUMAN.STOP_BASE_ACTION,flowNode.roleConfig.actionMoveOut.animation)
            
            console.log("Livekit节点列表", sceneStore.currentFlowNodes)
            sceneStore.currentFlowNodes.push(flowNode)
            roleMoving.value = false;
            if (!livekitFlowNodePlaying.value) {
              playLivekitFlowNodeList()
            }
          })
          
        }
        
    }
    
  }else{
    sceneStore.currentFlowNodes.push(flowNode)
    if (!livekitFlowNodePlaying.value) {
      playLivekitFlowNodeList()

    }
    console.log("Livekit节点列表", sceneStore.currentFlowNodes)
  }
  
}

function clearLivekitFlowNode() {
  flowImageList.value = [];
  flowVideoList.value = [];
  flowSvgAnimList.value = [];
  
  livekitFlowNodePlaying.value = false;
  timelineRef.value.pause();
  timelineRef.value.onEnded = null;
  if (sceneStore.currentFlowNodes.length > 0) {
    
    sceneStore.currentFlowNodes = []
    curLivekitFlowNodeIndex.value = 0

    
  }

}

function playLivekitFlowNodeList() {
  
  clearTimeout(noReplytimeout)
  startFlowNodeList()
  
  console.log("开始播放Livekit节点", curLivekitFlowNodeIndex.value)
  //向父窗口发送默认退出事件
  sendMessageToParent('timeline-event','timeline-start',{id:sceneStore.currentFlowNodes[curLivekitFlowNodeIndex.value].id,question:sceneStore.currentQuestion,questionType:sceneStore.currentQuestionType})
  setFlowNode(sceneStore.currentFlowNodes[curLivekitFlowNodeIndex.value])
  if (sceneStore.currentFlowNodes[curLivekitFlowNodeIndex.value].type && sceneStore.currentFlowNodes[curLivekitFlowNodeIndex.value].type == 'static') {
    timelineRef.value.onEnded = function () {
      //向父窗口发送默认退出事件
      sendMessageToParent('timeline-event','timeline-leave',{speechText:sceneStore.currentFlowNodes[curLivekitFlowNodeIndex.value].speechWordsList[0].timelineData.speechData[0].text,id:sceneStore.currentFlowNodes[curLivekitFlowNodeIndex.value].id,question:sceneStore.currentQuestion,questionType:sceneStore.currentQuestionType})
      flowImageList.value = [];
      flowVideoList.value = [];
      flowSvgAnimList.value = [];
      curLivekitFlowNodeIndex.value += 1
      if (sceneStore.currentFlowNodes.length > 0 && (curLivekitFlowNodeIndex.value < sceneStore.currentFlowNodes.length)) {
        console.log("播放下一个Livekit节点", curLivekitFlowNodeIndex.value)
        setFlowNode(sceneStore.currentFlowNodes[curLivekitFlowNodeIndex.value])
      } else {
        //结束所有Livekit节点
        finishFlowNodeList()
      }
      
    }

  } else if (sceneStore.currentFlowNodes[curLivekitFlowNodeIndex.value].type && sceneStore.currentFlowNodes[curLivekitFlowNodeIndex.value].type == 'dynamic') {
    timelineRef.value.onEnded = function () {
      //向父窗口发送默认退出事件
      sendMessageToParent('timeline-event','timeline-leave',{speechText:sceneStore.currentFlowNodes[curLivekitFlowNodeIndex.value].speechWordsList[0].timelineData.speechData[0].text,id:sceneStore.currentFlowNodes[curLivekitFlowNodeIndex.value].id,question:sceneStore.currentQuestion,questionType:sceneStore.currentQuestionType})
      flowImageList.value = [];
      flowVideoList.value = [];
      flowSvgAnimList.value = [];
      curLivekitFlowNodeIndex.value += 1
      if (sceneStore.currentFlowNodes.length > 0 && (curLivekitFlowNodeIndex.value < sceneStore.currentFlowNodes.length)) {
        console.log("播放下一个Livekit节点", curLivekitFlowNodeIndex.value)
        setFlowNode(sceneStore.currentFlowNodes[curLivekitFlowNodeIndex.value])
      } else {
        //结束所有Livekit节点
        finishFlowNodeList()
      }
    }
    // timelineRef.value.onEnded = function () {
    //   if ((curLivekitFlowNodeIndex.value >= sceneStore.currentFlowNodes.length) && chatboxRef.value.recording) {
    //     //恢复麦克风
    //     // emitter.emit(mittTypes.LIVEKIT.AUDIO_ENABLE, true)
    //   }
    // }
  } else {
    timelineRef.value.onEnded = function () {
      //向父窗口发送默认退出事件
      sendMessageToParent('timeline-event','timeline-leave',{speechText:sceneStore.currentFlowNodes[curLivekitFlowNodeIndex.value].speechWordsList[0].timelineData.speechData[0].text,id:sceneStore.currentFlowNodes[curLivekitFlowNodeIndex.value].id,question:sceneStore.currentQuestion,questionType:sceneStore.currentQuestionType})
      flowImageList.value = [];
      flowVideoList.value = [];
      flowSvgAnimList.value = [];
      curLivekitFlowNodeIndex.value += 1
      if (sceneStore.currentFlowNodes.length > 0 && (curLivekitFlowNodeIndex.value < sceneStore.currentFlowNodes.length)) {
        console.log("播放下一个Livekit节点", curLivekitFlowNodeIndex.value)
        setFlowNode(sceneStore.currentFlowNodes[curLivekitFlowNodeIndex.value])
      } else {
        //结束所有Livekit节点
        finishFlowNodeList()
      }
    }

  }
}

let noReplytimeout = setTimeout(() => {

}, 30000);
let noUserReplyTip = false 
let noUserReplyTipFinish = false 

function finishFlowNodeList() {
  //向父窗口发送默认完成事件
  sendMessageToParent('timeline-event','timeline-finish',{})
  livekitFlowNodePlaying.value = false;
  console.log("结束所有Livekit节点")
  emitter.emit(mittTypes.RENDERER.FLOWNODE_LIST_END)
  asking = false;
  clearLivekitFlowNode();
  

  //数字人播完节点后 用户未回复提示
  if (noUserReplyTip) {
    // if(sleepTime.value>=40000){
    //   noReplytimeout =  setTimeout(() => {
    //     console.log("30秒提示用户未回复")
    //     emitter.emit(mittTypes.CHATBOX.ADD_MESSAGE,sceneStore.projectConfig.roleConfig.roleSpeech.noReplySpeech.text)
    //     addLivekitFlowNode(sceneStore.projectConfig.roleConfig.roleSpeech.noReplySpeech.flowNode)
    //     noUserReplyTip = false;
    //   }, 30000);

    // }else{

    // }
    if (sleepTime.value >= 20000) {
      console.log("用户未回复开始计时" + (sleepTime.value - 10000) / 1000 + '秒')
      if (noReplytimeout) {
        clearTimeout(noReplytimeout);
      }
      noReplytimeout = setTimeout(() => {
        if(currentProjectPlatform.value == 'guide'){
          return;
        }
        console.log("休眠前10秒提示用户未回复")
        emitter.emit(mittTypes.CHATBOX.ADD_MESSAGE, sceneStore.projectConfig.roleConfig.roleSpeech.noReplySpeech.text)
         if(currentProjectType.value == '2d'){
          emitter.emit(mittTypes.LIVEKIT.DRIVE_2D_BY_URL,sceneStore.projectConfig.roleConfig.roleSpeech.noReplySpeech.flowNode.speechWordsList[0].timelineData.speechData[0].src)
        }
        addLivekitFlowNode(sceneStore.projectConfig.roleConfig.roleSpeech.noReplySpeech.flowNode)
        noUserReplyTip = false;
        noUserReplyTipFinish = true;
        // 用于用户未设置提示回复语时 没有播放livekitnode 则直接进入休眠计时
        timeout = setTimeout(() => {

          console.log("提醒" + sleepTime.value + "秒开始进入睡眠模式")
          gotoSleep(false);
        }, 10000);
      }, sleepTime.value - 10000);
    }

  }else if(noUserReplyTipFinish){
      console.log("开始10秒倒计时进入睡眠")
      // 用于用户设置提示回复语时 播放完livekitnode 进入休眠计时
      timeout = setTimeout(() => {
        console.log("提醒" + sleepTime.value + "秒开始进入睡眠模式")
        gotoSleep(false);
      }, 10000);
  }

}

function startFlowNodeList() {
 
  livekitFlowNodePlaying.value = true;
}

function playSleepFlowNodeList(flowNodeList: any) {
  setFlowNode(flowNodeList[0])
  console.log("开始播放节点", currentSleepFlowNodeIndex.value)
  timelineRef.value.onEnded = function () {
    setTimeout(() => {
      if (sceneStore.isSleeping) {
        currentSleepFlowNodeIndex.value += 1

        if (currentSleepFlowNodeIndex.value < flowNodeList.length) {
          console.log("播放下一个节点")
          setFlowNode(flowNodeList[currentSleepFlowNodeIndex.value])
          if(currentProjectType.value == '2d'){
            let localUrl=flowNodeList[currentSleepFlowNodeIndex.value].speechWordsList[0].timelineData.speechData[0].src;
            emitter.emit(mittTypes.LIVEKIT.DRIVE_2D_BY_URL,localUrl)
          }
          
        } else {
          console.log("播放初始节点")
          currentSleepFlowNodeIndex.value = 0
          setFlowNode(flowNodeList[0])
          if(currentProjectType.value == '2d'){
            let localUrl=flowNodeList[0].speechWordsList[0].timelineData.speechData[0].src;
            emitter.emit(mittTypes.LIVEKIT.DRIVE_2D_BY_URL,localUrl)
          }
          
        }
      }

    }, 3000);

  }
}

function gotoSleep(asr) {
  if(timelineRef.value.isPlaying){
    emitter.emit(mittTypes.SLEEPING_CONTROL.UPDATE_WAKEUP_STATUS)
    emitter.emit(mittTypes.CHATBOX.UPDATE_USER_ACTIVE)
    console.log("数字人播报中，重新计时睡眠")
    return;
  }
  console.log("开始进入睡眠模式")
  //清除等待词语音
  emitter.emit(mittTypes.CHATBOX.CLEAR_WAITING_TIMEOUT);
  clearTimeout(noReplytimeout)
  sceneStore.isSleeping = true;
  currentSleepState.value = true;
  clearLivekitFlowNode();
  switch (sceneStore.projectConfig.sleepConfig.sleepType) {
    case 'flow':
      const commonElements = sceneStore.projectConfig.flowNodeConfig.filter(item1 =>
          sceneStore.projectConfig.sleepConfig.sleepParams.flowList.some(item2 => item1.id === item2.id)
      );
      if (commonElements) {
        console.log("#sleep node:", commonElements)
        playSleepFlowNodeList(commonElements)
      }

      break;
    case 'image':
      break;
    case 'video':
      setTimeout(() => {
        videoSleepRef.value.play();
        videoSleepRef.value.onended = function () {
          currentSleepVideoIndex.value += 1;
          if (currentSleepVideoIndex.value < sceneStore.projectConfig.sleepConfig.sleepParams.videoList.length) {

            videoSleepRef.value.src = origin + sceneStore.projectConfig.sleepConfig.sleepParams.videoList[currentSleepVideoIndex.value].url
          } else {
            currentSleepVideoIndex.value = 0;
            videoSleepRef.value.src = origin + sceneStore.projectConfig.sleepConfig.sleepParams.videoList[currentSleepVideoIndex.value].url
          }
          videoSleepRef.value.play();
        }
      }, 100);

      break;
  }
  emitter.emit(mittTypes.LIVEKIT.AUDIO_ENABLE_AGENT, false)
  emitter.emit(mittTypes.SLEEPING_CONTROL.ON_SLEEP_START)
  //agent端处理 无需前端返回了
  if (!asr) {
    emitter.emit(mittTypes.LIVEKIT.SLEEP_AGENT)
  }
  if (chatboxRef.value && !chatboxRef.value.recording) {
    //恢复麦克风 否则无法语音唤醒
    chatboxRef.value.recording = true;
    emitter.emit(mittTypes.LIVEKIT.AUDIO_ENABLE, true)
  }
}

function wakeUp(asr) {

  // 唤醒取消暂停状态
  stopLivekitFlowNodeList.value = false;
  if (timelineRef.value) {
    timelineRef.value.pause(true);

    timelineRef.value.onEnded = null;
  }

  currentSleepState.value = false;
  currentSleepFlowNodeIndex.value = 0
  if (sceneStore.projectConfig.sleepConfig.sleepType == 'video') {
    if (videoSleepRef.value) {
      videoSleepRef.value.pause();
    }
  }
  if(currentProjectType.value == '2d'){
    emitter.emit(mittTypes.LIVEKIT.DRIVE_2D_BY_TEXT,'')
  }
  //agent端处理 无需前端返回了
  if (!asr) {

    chatboxRef.value.addLoadingReplyItem();
    emitter.emit(mittTypes.LIVEKIT.WAKEUP_AGENT, true)
  }

}

function setAnimationRef(el) {
  if (el) {
    sceneStore.animationRefList.push(el)
  }

}

function setSvgAnimRef(el) {
  if (el) {
    sceneStore.svgAnimRefList.push(el)
  }

}

// 添加监听父节点消息的方法
function handleParentMessage(event: MessageEvent) {
  // 安全检查，确保消息来源可信
  if (!event.data || typeof event.data !== 'object') {
    return;
  }

  const {type, data} = event.data;

  // 监听 PLAY_FLOWNODE 事件
  if (type === mittTypes.RENDERER.PLAY_FLOWNODE) {
    console.log('收到父节点播放流程节点消息:', data);
    if(currentProjectType.value === 'Web3d'){
      if(livekitFlowNodePlaying.value){
        //打断之前正在播放的内容
        emitter.emit(mittTypes.LIVEKIT.STOP_REPLY)
      }
    }
    
    playFlowNodeById(data.id);
  }else if(type == mittTypes.LIVEKIT.TEXT_DRIVE){
    // 监听文字驱动
    console.log('收到父节点文字驱动消息:', data);
    if(livekitFlowNodePlaying.value){
      //打断之前正在播放的内容
      emitter.emit(mittTypes.LIVEKIT.STOP_REPLY)
    }
    emitter.emit(mittTypes.LIVEKIT.TEXT_DRIVE, data.text)
  }else if(type == mittTypes.LIVEKIT.MESSAGE_SEND){
    // 监听文字提问
    console.log('收到父节点消息发送消息:', data);
    if(livekitFlowNodePlaying.value){
      //打断之前正在播放的内容
      emitter.emit(mittTypes.LIVEKIT.STOP_REPLY)
    }
    sceneStore.currentQuestion = data.text
    sceneStore.currentQuestionType = 'text'
    emitter.emit(mittTypes.LIVEKIT.MESSAGE_CHAT_RECIVE,{
        messageData:{message:data.text},
        from : mittTypes.LIVEKIT.MESSAGE_CHAT_FROM_TYPE.LOCAL
      })
    emitter.emit(mittTypes.LIVEKIT.MESSAGE_SEND, data.text)
  }else if(type == mittTypes.LIVEKIT.AUDIO_ENABLE){
    // 监听文字驱动
    console.log('收到父节点麦克风状态消息:', data);
    
    emitter.emit(mittTypes.LIVEKIT.AUDIO_ENABLE, data.enable)
  }
  else if(type == mittTypes.LOADING.START_SCENE){
    console.log('收到父节点开始场景消息:', data);
    emitter.emit(mittTypes.LOADING.START_SCENE_CLICK)
    // if(document.getElementById('AiHumanPlayBtn')){
    //     document.getElementById('AiHumanPlayBtn').click()
    // }
    // emitter.emit(mittTypes.HUMAN2D.PLAY_RTC)
  }else if(type == 'show_voice_anim'){
    console.log('收到父节点显示声音动画消息:', data.show);
    emitter.emit(mittTypes.LIVEKIT.ASR_SHOW_VOICEANIM,data.show)
    // if(document.getElementById('AiHumanPlayBtn')){
    //     document.getElementById('AiHumanPlayBtn').click()
    // }
    // emitter.emit(mittTypes.HUMAN2D.PLAY_RTC)
  }else if(type == mittTypes.LIVEKIT.STOP_REPLY){
    console.log('收到父节点打断消息:', data.show);
    //打断之前正在播放的内容
    emitter.emit(mittTypes.LIVEKIT.STOP_REPLY)
    emitter.emit(mittTypes.WEBHUMAN.STOP_VISEME_AUDIO)
    let random = Math.floor(Math.random() * sceneStore.projectConfig.uiConfig.interrupt.interruptResponses.length);
    emitter.emit(mittTypes.RENDERER.SET_FLOWNODE,sceneStore.projectConfig.uiConfig.interrupt.interruptResponses[random].flowNode)
    emitter.emit(mittTypes.CHATBOX.ADD_MESSAGE,sceneStore.projectConfig.uiConfig.interrupt.interruptResponses[random].text)
  }
}


// 根据 id 播放指定的 flownode
function playFlowNodeById(flowNodeId: string) {
  if (!sceneStore.projectConfig || !sceneStore.projectConfig.flowNodeConfig) {
    console.error('项目配置或流程节点配置不存在');
    return;
  }

  // 在项目配置中查找指定 id 的 flownode
  const targetFlowNode = sceneStore.projectConfig.flowNodeConfig.find(
      (flowNode: any) => flowNode.id === flowNodeId
  );

  if (!targetFlowNode) {
    console.error(`未找到 id 为 ${flowNodeId} 的流程节点`);
    return;
  }

  console.log('找到目标流程节点，开始播放:', targetFlowNode);

  // 参考 livekitManager 中的处理方式
  const temp = {
    data: {type: 'static',command:"multi_modal_data",segmentId:uuid(),requestId:uuid(),data:[targetFlowNode]}
  };
 
  if (currentProjectType.value === 'UE3d' || currentProjectType.value === '2d') {
    // 对于 UE3d 和 2d 类型，添加到流程节点列表中播放
    // addLivekitFlowNode(targetFlowNode);
    emitter.emit(mittTypes.LIVEKIT.SET_MULTIDATA, temp);
      emitter.emit(mittTypes.RENDERER.ADD_FLOWNODE, targetFlowNode);
    
    
    // emitter.emit(mittTypes.LIVEKIT.DRIVE_UE_BY_FLOWNODE, targetFlowNode);
  } else if (currentProjectType.value === 'Web3d') {
    
    // 对于 Web3d 类型，直接触发渲染器添加流程节点事件
    emitter.emit(mittTypes.RENDERER.ADD_FLOWNODE, targetFlowNode);
  }
}
let curid = null
let curtext = ''
let curPinyintext = ''
let asking = false
let interrupt = false
function addAndroidControlFunction(){
  
  window.receiveAndroidAsr = function(id,text,end){
    
    let pinyindecodeMsg = pinyin(curtext.replace(/[^\u4e00-\u9fa5a-zA-Z0-9]/g, ""), {
      style: pinyin.STYLE_NORMAL, // 设置拼音样式为普通风格
      heteronym: false // 不考虑多音字
    }).join('-')
    // 正在回答时 判断是否有唤醒词
    if(asking){
      // 收到唤醒词 打断上一条回复 提问新的问题
      // if(sceneStore.projectConfig.wakeConfig.wakeParams.wakeWord&&sceneStore.projectConfig.wakeConfig.wakeParams.wakeWord instanceof Array){
      //   let finded = false;
      //   sceneStore.projectConfig.wakeConfig.wakeParams.wakeWord.forEach(element => {
      //     if(curtext.indexOf(element)>-1){
      //       emitter.emit(mittTypes.LIVEKIT.STOP_REPLY)
      //       finded = true;
      //     }
      //   });
      //   if(!finded){
      //      // 没有唤醒词 不处理
      //     return;
      //   }
      // }else if(sceneStore.projectConfig.wakeConfig.wakeParams.wakeWord){
      //   if(curtext.indexOf(sceneStore.projectConfig.wakeConfig.wakeParams.wakeWord)>-1){
      //     emitter.emit(mittTypes.LIVEKIT.STOP_REPLY)
      //   }else{
      //      // 没有唤醒词 不处理
      //     return;
      //   }
      // }else{
      //   // 没有唤醒词 不处理
      //   return;
      // }
      if(curid&&curid == id){
        curPinyintext += text
      }else{
        curid = id
        curPinyintext = text
      }
      sceneStore.projectConfig.interrupt.voiceInterruptWords.forEach((interruptword,index) => {
        let pinyinterruptWord = pinyin(interruptword.replace(/[^\u4e00-\u9fa5a-zA-Z0-9]/g, ""), {
          style: pinyin.STYLE_NORMAL, // 设置拼音样式为普通风格
          heteronym: false // 不考虑多音字
        }).join('-')
        if(pinyindecodeMsg == pinyinterruptWord){
          interrupt = true
        }
      });
      if(interrupt){
        // 识别打断词拼音 进行打断回复处理
        emitter.emit(mittTypes.LIVEKIT.STOP_REPLY)
        // let random = Math.floor(Math.random() * sceneStore.projectConfig.uiConfig.interrupt.interruptResponses.length);
        // emitter.emit(mittTypes.RENDERER.SET_FLOWNODE,sceneStore.projectConfig.uiConfig.interrupt.interruptResponses[random].flowNode)
        // emitter.emit(mittTypes.CHATBOX.ADD_MESSAGE,sceneStore.projectConfig.uiConfig.interrupt.interruptResponses[random].text)

      }else{
        // 未识别到打断词 不处理
        return;
      }
    }else{
      if(curid&&curid == id){
        curtext += text
      }else{
        curid = id
        curtext = text
      }
    }
    
    
    emitter.emit(mittTypes.LIVEKIT.MESSAGE_CHAT_RECIVE,{
        messageData:{id:id,message:text},
        from : mittTypes.LIVEKIT.MESSAGE_CHAT_FROM_TYPE.LOCAL
    })
   
    if(end){
      emitter.emit(mittTypes.LIVEKIT.MESSAGE_SEND, curtext)
      asking = true;
    }
    
  }
  window.showVoiceAnim = function(show){
    
    emitter.emit(mittTypes.LIVEKIT.ASR_SHOW_VOICEANIM,show)
  }
  window.wakeupStatus = function(){
    
    emitter.emit(mittTypes.SLEEPING_CONTROL.WAKEUP)
  }
  window.updateWakeupStatus = function(){
    
    emitter.emit(mittTypes.SLEEPING_CONTROL.UPDATE_WAKEUP_STATUS)
    emitter.emit(mittTypes.CHATBOX.UPDATE_USER_ACTIVE)
  }
  window.sleepStatus = function(){
    
    emitter.emit(mittTypes.SLEEPING_CONTROL.SLEEP)
  }
}

onMounted(async () => {
  // 添加父节点消息监听器
  window.addEventListener('message', handleParentMessage);
  addAndroidControlFunction();

  let projectId = getUrlParam('id') + "_" + new Date().getTime();
  console.log('projectId',projectId);
  sendMessageToParent('project-event','id',{projectId:projectId})
  // close2d({
  //   resource_code:'res_3b87f31220250217132251',
  //     })
  //     return;
  // beforeunload 的回调，弹出提示，确认是否刷新或关闭浏览器
  let bfcallback = async (e) => {
    var dialogText = '确定要离开吗';
    e.returnValue = dialogText;

    if (sceneStore.livekitRoom) {
      // emitter.emit(mittTypes.LIVEKIT.SLEEP_AGENT)
      sceneStore.livekitRoom.disconnect();
      closeRoom({
        roomName: sceneStore.livekitRoom.name
      })
    }

    // 在 beforeunload 中执行关闭操作
    if (sceneStore.projectConfig.projectSet.type == '2d') {
      try {
        // 使用 sendBeacon 发送请求，这个 API 专门用于页面卸载时发送数据
        // navigator.sendBeacon('/api/close2d', JSON.stringify({
        //   projectId: projectId
        // }));
        close2d({
          projectId: projectId
        })

        // if (sceneStore.livekitRoom) {
        //   sceneStore.livekitRoom.disconnect();
        // }

        // closeRoom({
        //   roomName: sceneStore.livekitRoom.name
        // })
      } catch (err) {
        console.error('Close 2d failed:', err);
      }
    }

    if (sceneStore.projectConfig.projectSet.type == 'UE3d') {
      try {
        // navigator.sendBeacon('/api/closeUe', JSON.stringify({
        //   // serverId: ueHumanServerId.value,
        //   // ueId: ueHumanStreamerId.value
        //   projectId:projectId
        // }));
        closeUe({
          
          ueId: ueHumanStreamerId.value
        })

        // if (sceneStore.livekitRoom) {
        //   sceneStore.livekitRoom.disconnect();
        // }
        // closeRoom({
        //   roomName: sceneStore.livekitRoom.name
        // })
      } catch (err) {
        console.error('Close UE failed:', err);
      }
    }


    return dialogText;
  }

  // 移除 unload 事件监听,只使用 beforeunload
  if(getUrlParam('noExitTip') == '1'){

  }else{
    window.addEventListener('beforeunload', bfcallback);
  }
  
  // let project = await getProjectAllConfigInfo({id:"1803245434144567297"})

  let project = await getProjectAllConfigInfo({id: projectId})
  let projectConfig = project.data
  sceneStore.projectConfig = projectConfig
  console.log("project:", projectConfig)
  let projectDetail = await getAimetaProjectManagerdetailInfo({id: projectId})
  document.title = projectDetail.data.projectName
  console.log("projectDetail:", projectDetail.data)
  let animataDetail = await getAimetaManagerdetailInfo({id: projectDetail.data.aimetaId})
  console.log("animataDetail:", animataDetail)

  sceneStore.timelineRef = timelineRef

  if (projectConfig.projectSet.type) {
    currentProjectType.value = projectConfig.projectSet.type
  }
  if (projectConfig.projectSet.platform) {
    currentProjectPlatform.value = projectConfig.projectSet.platform
  }
  if (projectConfig.uiConfig.historySet) {
    currentInputType.value = projectConfig.uiConfig.historySet.type
  }

  let serverInfo = await getTokenToBegin({
    configJson: project.data,
    clientType: 1
  })
  // let serverInfo2 = await getTokenToBegin({
  //   configJson:project.data,
  //   clientType:2
  // })
  // console.log('serverInfo2',serverInfo2)

  // ue或2d数字人提前链接进房间 并静音 等待开始后取消静音 发送唤醒消息
  if (projectConfig.projectSet.type == 'UE3d' || projectConfig.projectSet.type == '2d') {
    livkitToken.value = serverInfo.data.wsServer.token
    livkitUrl.value = serverInfo.data.wsServer.url
  } else {
    livkitToken.value = serverInfo.data.wsServer.token
    livkitUrl.value = serverInfo.data.wsServer.url
  }

  switch (projectConfig.projectSet.platform) {
    case 'pc':
      resolutionPolicy.value.width = 1920
      resolutionPolicy.value.height = 1080
      if (window.innerWidth / window.innerHeight > 16 / 9) {
        resolutionPolicy.value.policy = 'FIXED_HEIGHT'
      }
      break;
    case 'mobile':
      resolutionPolicy.value.width = 1080
      resolutionPolicy.value.height = 1920
      if (window.innerWidth / window.innerHeight > 9 / 16) {
        resolutionPolicy.value.policy = 'FIXED_HEIGHT'
      }
      break;
    case 'screen':
      resolutionPolicy.value.width = 1080
      resolutionPolicy.value.height = 1920
      if (window.innerWidth / window.innerHeight > 9 / 16) {
        resolutionPolicy.value.policy = 'FIXED_HEIGHT'
      }
      break;
  }

  if (projectConfig.uiConfig.chatbox) {
    chatboxParams.value.box = projectConfig.uiConfig.chatbox.box
    chatboxParams.value.input = projectConfig.uiConfig.chatbox.input
    chatboxParams.value.questions = projectConfig.uiConfig.chatbox.questions
  }
  fullBody.value = projectConfig.uiConfig.modelSet.fullBody
  if (projectConfig.projectSet.type == 'Web3d') {
    emitter.emit(mittTypes.LOADING.SET_LOADING_STYLE, 'progress')
    webHumanParams.value.x = parseFloat(projectConfig.uiConfig.modelSet.x)
    webHumanParams.value.y = parseFloat(projectConfig.uiConfig.modelSet.y)
    webHumanParams.value.width = parseFloat(projectConfig.uiConfig.modelSet.width)
    webHumanParams.value.height = parseFloat(projectConfig.uiConfig.modelSet.height)

    webHumanUrl.value = origin + projectConfig.uiConfig.modelSet.modelAppearance
    // webHumanUrl.value = origin + animataDetail.data.costumesPackageInfo.costumePackage.fileUrl
    if (animataDetail.data.costumesList) {
      animataDetail.data.costumesList.forEach(element => {
        webHumanCostumeList.value.push(origin + element.costumesFile)
      });
    }

    if (animataDetail.data.actionPackageInfo.actionList) {
      animataDetail.data.actionPackageInfo.actionList.forEach(element => {
        webHumanActionList.value.push({url: origin + element.animateFile, name: element.actionName})
        // webHumanActionList.value.push({url: origin + animataDetail.data.actionPackageInfo.actionPackage.fileUrl, name: element.actionName})
        webHumanActions.value.push(element.actionName)
      });
    }


  } else if (projectConfig.projectSet.type == 'UE3d') {
    emitter.emit(mittTypes.LOADING.SET_LOADING_STYLE, 'spin')
    ueHumanParams.value.x = projectConfig.uiConfig.modelSet.x
    ueHumanParams.value.y = projectConfig.uiConfig.modelSet.y
    ueHumanParams.value.width = projectConfig.uiConfig.modelSet.width
    ueHumanParams.value.height = projectConfig.uiConfig.modelSet.height
    // await closeUe({
    //   serverId:'1869656051219869801',
    //   ueId:'AiHumanStream1'
    // })
    // await closeUe({
    //   serverId:'1869656051219869801',
    //   ueId:'AiHumanStream2'
    // })
    // await closeUe({
    //   serverId:'1869656051219869801',
    //   ueId:'AiHumanStream3'
    // })
    emitter.on(mittTypes.LIVEKIT.CONNECT_SUCCESS, async function (data: any) {
      setTimeout(async () => {
        let ueInfo = await getCanOpenAndOpenUe({
          projectId: projectId
        })
        if (!ueInfo.data) {
          ElMessage.error("没有可用的UE服务器")
        } else {
          ueHumanServerId.value = ueInfo.data.serverId
          ueHumanUrl.value = ueInfo.data.streamUrl
          ueHumanStreamerId.value = ueInfo.data.ueId
        }
      }, 1000);

    })


  } else if (projectConfig.projectSet.type == '2d') {
    emitter.emit(mittTypes.LOADING.SET_LOADING_STYLE, 'spin')
    Human2dParams.value.x = projectConfig.uiConfig.modelSet.x
    Human2dParams.value.y = projectConfig.uiConfig.modelSet.y
    Human2dParams.value.width = projectConfig.uiConfig.modelSet.width
    Human2dParams.value.height = projectConfig.uiConfig.modelSet.height
    // await closeUe({
    //   serverId:'1869656051219869801',
    //   ueId:'AiHumanStream1'
    // })
    // await closeUe({
    //   serverId:'1869656051219869801',
    //   ueId:'AiHumanStream2'
    // })
    // await closeUe({
    //   serverId:'1869656051219869801',
    //   ueId:'AiHumanStream3'
    // })
    emitter.on(mittTypes.LIVEKIT.CONNECT_SUCCESS, async function (data: any) {
      if (false) {
        async function open2d() {
          let human2dInfo = await getCanOpenAndOpen2d({
            projectId: projectId
          })

          function handleResult() {
            let interval = setInterval(async () => {
              let openResult = await get2dResourceApplyResult({
                projectId: projectId
              })
              if (openResult.code == 200) {
                switch (openResult.data.status) {
                  case 4:
                    // emitter.emit(mittTypes.LOADING.LOAD_FINISH)

                    //emitter.emit(mittTypes.LOADING.UPDATE_LOADING_WORD,'数字人等待播放中...')
                    clearInterval(interval);
                    Human2dUrl.value = openResult.data.stream_id
                    Human2dConfig.value.urls = openResult.data.urls
                    Human2dConfig.value.username = openResult.data.username
                    Human2dConfig.value.credential = openResult.data.credential
                    resource2dCode.value = openResult.data.resource_code
                    // webhuman2dRenderRef.value.rtcVideo.play();
                    //已启动
                    break;
                  case 0:
                    emitter.emit(mittTypes.LOADING.UPDATE_LOADING_WORD, '数字人等待启动中...')
                    //等待启动
                    resource2dCode.value = openResult.data.resource_code
                    break;
                  case 2:
                    emitter.emit(mittTypes.LOADING.UPDATE_LOADING_WORD, '数字人正在启动...')
                    //启动中
                    resource2dCode.value = openResult.data.resource_code
                    break;
                  case -1:
                    //启动失败 cpu不足
                    clearInterval(interval);
                    break;
                  case -2:
                    //启动失败 gpu不足
                    clearInterval(interval);
                    break;
                  case -3:
                    //启动失败 不明原因
                    clearInterval(interval);
                    break;
                  case 6:
                    //进程已经申请关闭
                    clearInterval(interval);
                    break;
                }

              }
              console.log(openResult)
            }, 1000);
          }

          if (!human2dInfo.data) {
            // ElMessage.error({message:"没有可用的数字人,请耐心等待或稍后再试",grouping: true,})
            emitter.emit(mittTypes.LOADING.UPDATE_LOADING_WORD, '没有可用的数字人,请耐心等待或稍后再试,正在重连...')
            setTimeout(() => {
              open2d();
            }, 5000);

          } else {
            console.log('2dInfo', human2dInfo)
            handleResult()

            // ueHumanServerId.value = ueInfo.data.serverId
            // ueHumanUrl.value = ueInfo.data.streamUrl
            // ueHumanStreamerId.value = ueInfo.data.ueId
          }
        }

        setTimeout(async () => {
          open2d()
        }, 1000);

      } else {
        Human2dUrl.value = 'https://aimeta.huilan.com:32109'
        Human2dConfig.value.urls = 'turn:aihuman.huilan.com:19303'
        Human2dConfig.value.username = 'PixelStreamingUser'
        Human2dConfig.value.credential = 'AnotherTURNintheroad'
      }

    })
  }
  if(projectConfig.projectSet.platform == 'guide'){
    emitter.emit(mittTypes.LOADING.SET_LOADING_STYLE, 'none')
  }


  flowNodes.value = projectConfig.flowNodeConfig
  if (flowNodes.value.length > 0) {
    sendMessageToParent('flownode-event','list',{flowNodeList:projectConfig.flowNodeConfig})
    // currentFlowNode.value = flowNodes.value[0];

    // flowImageList.value = flowNodes.value[0].imageList;
    // flowVideoList.value = flowNodes.value[0].videoList;
    // flowSvgAnimList.value = flowNodes.value[0].svgAnimList;

    // sceneStore.currentFlowNode = flowNodes.value[0]

    // setTimeout(() => {
    //   sceneStore.animationRefList.forEach(function(animref){
    //     // animref.setShowAnimation(false)

    //   })
    //   timelineRef.value.play()
    // }, 500);

  }


  imageList.value = projectConfig.uiConfig.imageList
  videoList.value = projectConfig.uiConfig.videoList
  iframeList.value = projectConfig.uiConfig.webList
  textList.value = projectConfig.uiConfig.textList
  if (projectConfig.uiConfig.htmlTextList) {
    htmlTextList.value = projectConfig.uiConfig.htmlTextList
  }

  sleepTime.value = parseFloat(projectConfig.sleepConfig.sleepTime) * 1000
  if (sceneStore.projectConfig.uiConfig.captions) {
    captionsParams.value.enable = sceneStore.projectConfig.uiConfig.captions.enable
    captionsParams.value.x = sceneStore.projectConfig.uiConfig.captions.x
    captionsParams.value.y = sceneStore.projectConfig.uiConfig.captions.y
    captionsParams.value.width = sceneStore.projectConfig.uiConfig.captions.width
    captionsParams.value.height = sceneStore.projectConfig.uiConfig.captions.height
    captionsParams.value.zindex = sceneStore.projectConfig.uiConfig.captions.zindex
    captionsParams.value.style.fontSize = sceneStore.projectConfig.uiConfig.captions.fontSize + 'px'
    captionsParams.value.style.backgroundColor = sceneStore.projectConfig.uiConfig.captions.backgroundColor
    captionsParams.value.style.border = "2px solid " + sceneStore.projectConfig.uiConfig.captions.borderColor
    captionsParams.value.style.color = sceneStore.projectConfig.uiConfig.captions.color
    captionsParams.value.style.lineHeight = sceneStore.projectConfig.uiConfig.captions.lineHeight
  }
  // voiceInput 初始化部分
  if (sceneStore.projectConfig.uiConfig.voiceInput) {
    voiceInputParams.value.enable = sceneStore.projectConfig.uiConfig.voiceInput.enable
    voiceInputParams.value.x = sceneStore.projectConfig.uiConfig.voiceInput.x
    voiceInputParams.value.y = sceneStore.projectConfig.uiConfig.voiceInput.y
    voiceInputParams.value.width = sceneStore.projectConfig.uiConfig.voiceInput.width
    voiceInputParams.value.height = sceneStore.projectConfig.uiConfig.voiceInput.height
    voiceInputParams.value.zindex = sceneStore.projectConfig.uiConfig.voiceInput.zindex
    voiceInputParams.value.opacity = sceneStore.projectConfig.uiConfig.voiceInput.opacity
    voiceInputParams.value.url = sceneStore.projectConfig.uiConfig.voiceInput.url
  }
  if(sceneStore.projectConfig.uiConfig.cornerControl){
    cornerControlParams.value = sceneStore.projectConfig.uiConfig.cornerControl
    if(currentProjectPlatform.value == 'guide'||currentProjectPlatform.value == 'screen'){
      cornerControlParams.value.enable = false
    }
  }
  // 在 onMounted 中添加 interruptParams 的初始化代码
  if (sceneStore.projectConfig.uiConfig.interrupt) {
    interruptParams.value.buttonInterrupt = sceneStore.projectConfig.uiConfig.interrupt.buttonInterrupt
    interruptParams.value.tip = sceneStore.projectConfig.uiConfig.interrupt.tip

    if (sceneStore.projectConfig.uiConfig.interrupt.buttonOptions) {
      interruptParams.value.buttonOptions = sceneStore.projectConfig.uiConfig.interrupt.buttonOptions
    }

    if (sceneStore.projectConfig.uiConfig.interrupt.tipOptions) {
      interruptParams.value.tipOptions = sceneStore.projectConfig.uiConfig.interrupt.tipOptions
    }

    if (sceneStore.projectConfig.uiConfig.interrupt.voiceInterruptWords) {
      interruptParams.value.voiceInterruptWords = sceneStore.projectConfig.uiConfig.interrupt.voiceInterruptWords
    }

    if (sceneStore.projectConfig.uiConfig.interrupt.interruptResponses) {
      interruptParams.value.interruptResponses = sceneStore.projectConfig.uiConfig.interrupt.interruptResponses
    }
  }
  if (sceneStore.projectConfig.uiConfig.style && sceneStore.projectConfig.uiConfig.style != 'default') {
    if (sceneStore.projectConfig.uiConfig.style.type == 'custom') {
      if (sceneStore.projectConfig.uiConfig.style.param.html && sceneStore.projectConfig.uiConfig.style.param.html != '') {
        $('#externalUI').load(origin + sceneStore.projectConfig.uiConfig.style.param.html, function () {
          if (sceneStore.projectConfig.uiConfig.style.param.css && sceneStore.projectConfig.uiConfig.style.param.css != '') {
            addCss(sceneStore.projectConfig.uiConfig.style.param.cs)
          }
          if (sceneStore.projectConfig.uiConfig.style.param.js && sceneStore.projectConfig.uiConfig.style.param.js != '') {
            Promise.all([
              asynLoad(origin + sceneStore.projectConfig.uiConfig.style.param.js, false),
            ]).then(() => {
              setTimeout(() => {
                console.log("加载完毕后执行的操作");
              }, 200)
            }).catch(res => {
              ElMessage.error("加载异常")
            })
          }

        });
      }
    } else if (sceneStore.projectConfig.uiConfig.style.type == "scientific") {

      bgImage.value = 'https://aiimg.huilan.com/aiHuman/UIstyles/scientific/images/back.jpg'
      chatboxParams.value.input.backgroundColor = '#0017B0'
      chatboxParams.value.questions.backgroundColor = '#0017B000'
      let url = new URL(`../../styles/scientific/style.css`, import.meta.url).href
      addCss(url)
    }
  }

  bgImage.value = projectConfig.uiConfig.backgroundSet.url.indexOf('http') < 0 ? origin + projectConfig.uiConfig.backgroundSet.url : projectConfig.uiConfig.backgroundSet.url
  // if (projectConfig.projectSet.platform == 'guide') {

  // bgImage.value = projectConfig.uiConfig.backgroundSet.url.indexOf('http') < 0 ? origin + projectConfig.uiConfig.backgroundSet.url : projectConfig.uiConfig.backgroundSet.url
  // // bgImage.value = projectConfig.projectSet.platform == 'guide'?'transparent':projectConfig.uiConfig.backgroundSet.url.indexOf('http') < 0 ? origin + projectConfig.uiConfig.backgroundSet.url : projectConfig.uiConfig.backgroundSet.url

  // }
  // webHumanUrl.value = "https://aiimg.huilan.com/"+project.data.uiConfig.modelSet.modelAppearance


  // if(projectId == '1805122630329040898'){
  //   webHumanUrl.value = "https://aiimg.huilan.com/material/model/bucket-000000/1845686477328011266.glb"
  // }else if(projectId == '1803245434144567297'){
  //   webHumanUrl.value = "https://aiimg.huilan.com/material/model/bucket-000000/1845663967643488257.glb"
  // }

  // webHumanActionList.value = "https://aiimg.huilan.com/material/model/bucket-000000/1845031651313242114.glb"
  nextTick(() => {
   // 监听整个窗口变化
   window.addEventListener('resize', updateIframeTransform)
    
    // 初始化时也更新一次
    updateIframeTransform()
  })

  
  emitter.on(mittTypes.LOADING.START_SCENE, function (data: any) {
    if (projectConfig.projectSet.type == 'UE3d') {
    } else {
      // livkitToken.value = serverInfo.data.wsServer.token
      // livkitUrl.value = serverInfo.data.wsServer.url
    }

    // clearTimeout(timeout)
    // timeout = setTimeout(() => {

    //   console.log("初始" + sleepTime.value + "秒开始进入睡眠模式")
    //   gotoSleep(false);
    // }, sleepTime.value);
  })

  emitter.on(mittTypes.LIVEKIT.MESSAGE_CHAT_RECIVE, function (data: any) {
    let messageData = data.messageData;
    let from = data.from;
    if (messageData.message.indexOf('<|STT|>') >= 0) {
      return
    }
    if (from == mittTypes.LIVEKIT.MESSAGE_CHAT_FROM_TYPE.BOT) {
      // currentText.value = messageData.message
      stopLivekitFlowNodeList.value = false;
      //等待用户没有说话 提示
      noUserReplyTip = true;
    }
    if (from == mittTypes.LIVEKIT.MESSAGE_CHAT_FROM_TYPE.LOCAL) {
      //用户asr说话 取消暂停状态
      stopLivekitFlowNodeList.value = false;
      //用户说话 取消提示
      noUserReplyTip = false;
    }
  })
  emitter.on(mittTypes.LIVEKIT.MESSAGE_CHAT_UPDATE, function (data: any) {
    let messageData = data.messageData;
    let from = data.from;
    if (messageData.message.indexOf('<|STT|>') >= 0) {
      return
    }
    if (from == mittTypes.LIVEKIT.MESSAGE_CHAT_FROM_TYPE.BOT) {
      const text = currentText.value

      // currentText.value = messageData.message.replace(text,'')
    }
    if (from == mittTypes.LIVEKIT.MESSAGE_CHAT_FROM_TYPE.LOCAL) {
      //用户asr说话 取消暂停状态
      stopLivekitFlowNodeList.value = false;
    }

  })
  emitter.on(mittTypes.LIVEKIT.MESSAGE_SEND, async function (data: any) {
    //用户发送消息 取消暂停状态
    stopLivekitFlowNodeList.value = false;
  })
  emitter.on(mittTypes.RENDERER.PLAY_FLOWNODE, async function (data: any) {
    playFlowNodeById(data.id);
  })
  emitter.on(mittTypes.WEBHUMAN.STOP_VISEME_AUDIO, async function (data: any) {
    // 开启暂停状态 停止流程节点列表播放
    stopLivekitFlowNodeList.value = true;
    clearLivekitFlowNode()
    timelineRef.value.pause();

    console.log('收到停止回答按钮消息，停止回答表情和语音')
  })
  emitter.on(mittTypes.RENDERER.SET_FLOWNODE, function (data: any) {
    setFlowNode(data)

  })
  emitter.on(mittTypes.RENDERER.ADD_FLOWNODE, function (data: any) {
    addLivekitFlowNode(data)

  })
  emitter.on(mittTypes.RENDERER.CLEAR_FLOWNODE, function (data: any) {
    clearLivekitFlowNode()

  })
  emitter.on(mittTypes.RENDERER.SET_UE_FLOWNODE_LIST_END, function (data: any) {
    finishFlowNodeList()

  })
  emitter.on(mittTypes.RENDERER.SET_UE_FLOWNODE_LIST_START, function (data: any) {
    startFlowNodeList()

  })
  currentSleepType.value = sceneStore.projectConfig.sleepConfig.sleepType

  emitter.on(mittTypes.CHATBOX.UPDATE_USER_ACTIVE, function (stopReply: any) {
    //用户说话 取消未回复提示
    clearTimeout(noReplytimeout)
    //如果是打断则重新计算提示用户未回复时间 其他的为播放结束后更新
    if (stopReply) {
      console.log("用户未回复开始计时" + (sleepTime.value - 10000) / 1000 + '秒')
      if (noReplytimeout) {
        clearTimeout(noReplytimeout);
      }
      noReplytimeout = setTimeout(() => {
        if(currentProjectPlatform.value == 'guide'){
          return;
        }
        console.log("休眠前10秒提示用户未回复")
        emitter.emit(mittTypes.CHATBOX.ADD_MESSAGE, sceneStore.projectConfig.roleConfig.roleSpeech.noReplySpeech.text)
        if(currentProjectType.value == '2d'){
          emitter.emit(mittTypes.LIVEKIT.DRIVE_2D_BY_URL,sceneStore.projectConfig.roleConfig.roleSpeech.noReplySpeech.flowNode.speechWordsList[0].timelineData.speechData[0].src)
        }
        addLivekitFlowNode(sceneStore.projectConfig.roleConfig.roleSpeech.noReplySpeech.flowNode)
        noUserReplyTip = false;
        noUserReplyTipFinish = true;
        timeout = setTimeout(() => {

          console.log("提醒" + sleepTime.value + "秒开始进入睡眠模式")
          gotoSleep(false);
        }, 10000);
      }, sleepTime.value - 10000);
    }
  })
  emitter.on(mittTypes.CHATBOX.STOP_REPLY, function (data: any) {
    if (!sceneStore.isSleeping) {
      //非休眠状态下 打断 更新提示用户未回复时间
      noUserReplyTip = true;
      asking = false;
    }
  })
  emitter.on(mittTypes.SLEEPING_CONTROL.UPDATE_WAKEUP_STATUS, function (data: any) {
    clearTimeout(timeout)
    // timeout = setTimeout(() => {
    //   gotoSleep(false);
    //   console.log("刷新后" + sleepTime.value + "秒开始进入睡眠模式")
    // }, sleepTime.value);
  })
  emitter.on(mittTypes.SLEEPING_CONTROL.SLEEP, function (asr: any) {
    clearTimeout(timeout)
    clearTimeout(noReplytimeout)
    console.log("命令进入睡眠模式")
    gotoSleep(asr);
  })
  emitter.on(mittTypes.SLEEPING_CONTROL.WAKEUP, function (asr: any) {
    clearTimeout(timeout)
    wakeUp(asr);
    console.log("命令唤醒")
    // timeout = setTimeout(() => {
    //   console.log("唤醒后" + sleepTime.value + "秒开始进入睡眠模式")
    //   gotoSleep(asr);
    // }, sleepTime.value);
  })


  //移除监听
  // this.$once('hook:beforeDestroy', () => {
  //   window.removeEventListener('beforeunload', bfcallback);
  //   window.removeEventListener('unload', ulcallback);
  // });
})
</script>
<script lang="ts">
export default {
  name: 'renderContainer'
}
</script>
<style scoped lang="scss">
.wakeup-btn {
  width: 100px;
  height: 40px;
  background: linear-gradient(90deg, #128FF8, #AA63E1);
  box-shadow: 0px 4px 12px 0px rgba(19, 38, 59, 0.2);
  border-radius: 32px;
  position: absolute;
  bottom: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.center {
  background-position: center;
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto;
  text-align: center;
  background-size: cover;
}
</style>